package com.flow.framework.schedule.system.listener.lifecycle;

import com.flow.framework.common.util.verify.VerifyUtil;
import com.flow.framework.schedule.job.BaseScheduleJob;
import com.flow.framework.schedule.properties.local.LocalConfigProperties;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 任务job相关资源持有者
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/4/10
 */
public class JobResourceHolder {

    /**
     * 更新本地job相关配置的读写锁
     */
    private static final ReadWriteLock READ_WRITE_LOCK = new ReentrantReadWriteLock();

    /**
     * job的bean名称对应的bean缓存
     */
    private static final Map<String, BaseScheduleJob> BEAN_NAME_AND_BEAN_MAP = new ConcurrentHashMap<>(16);

    /**
     * job名称和对应的job配置缓存
     */
    private volatile static Map<String, LocalConfigProperties> jobNameAndConfigMapCache = null;

    /**
     * 根据bean名称获取bean
     *
     * @param beanName bean名称
     * @return bean
     */
    public static BaseScheduleJob getBean(String beanName) {
        return BEAN_NAME_AND_BEAN_MAP.get(beanName);
    }

    /**
     * 根据job名称获取对应的job配置
     *
     * @param jobName job名称
     * @return job配置
     */
    public static LocalConfigProperties getLocalConfigProperties(String jobName) {
        Lock lock = READ_WRITE_LOCK.readLock();
        lock.lock();
        try {
            if (VerifyUtil.isEmpty(jobNameAndConfigMapCache)) {
                return null;
            }
            return jobNameAndConfigMapCache.get(jobName);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取job名称和对应的配置缓存
     *
     * @return job名称和对应的配置缓存map
     */
    static Map<String, LocalConfigProperties> getJobNameAndConfigMap() {
        Lock lock = READ_WRITE_LOCK.readLock();
        lock.lock();
        try {
            if (VerifyUtil.isEmpty(jobNameAndConfigMapCache)) {
                return Collections.emptyMap();
            }
            return jobNameAndConfigMapCache;
        } finally {
            lock.unlock();
        }

    }

    /**
     * 设置job名称和对应的配置
     *
     * @param jobNameAndConfigMap job名称和对应的配置map
     */
    static void setJobNameAndConfigMap(Map<String, LocalConfigProperties> jobNameAndConfigMap) {
        Lock lock = READ_WRITE_LOCK.writeLock();
        lock.lock();
        try {
            jobNameAndConfigMapCache = jobNameAndConfigMap;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 缓存bean名称和对应的bean
     *
     * @param beanNameAndBeanMap bean名称和对应的bean map
     */
    static void cacheBeans(Map<String, BaseScheduleJob> beanNameAndBeanMap) {
        BEAN_NAME_AND_BEAN_MAP.putAll(beanNameAndBeanMap);
    }

    /**
     * 根据bean名称判断当前缓存是否包含bean
     *
     * @param beanName bean名称
     * @return 是否包含bean
     */
    static boolean isContainsBean(String beanName) {
        return BEAN_NAME_AND_BEAN_MAP.containsKey(beanName);
    }
}